package com.sea.base.start

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.util.SparseArray
import android.view.View
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.MainThread
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.sea.base.activities.BaseKtActivity
import com.sea.base.ext.global.DAY_MILLIS
import com.sea.base.ext.global.getCurrentMillis
import com.sea.base.ext.global.intentNew
import com.sea.base.ext.global.singleApplication
import com.sea.base.ext.view.startActivityForResultCancelOk
import com.sea.base.utils.ActivityStackManager
import java.util.concurrent.atomic.AtomicInteger

/**
 * 支持跳转回调的工具类，相关拓展见[startActivityForResultCancelOk]
 * 如果你没有activity也可以使用，当然也不建议这种方式
 */
object StartActivityForResultHelper {

    /**
     * 跳转时传入的标志性key，被跳转放可根据此来判断是否是回调式result
     * [isCallbackAndRebuild]
     */
    private const val INTENT_CALLBACK_CHECK_KEY = "StartActivityForResultActivity-CallbackKey"

    private val startDatas = SparseArray<(ActivityResult) -> Unit>()
    private val reqCodeIncrement = AtomicInteger((getCurrentMillis() % (365L * DAY_MILLIS)).toInt())

    /**
     * 跳转方法
     *
     * 注意：请确定[BaseKtActivity.supportRebuildData]为false，如果支持重建请使用自带的[BaseKtActivity.registerForActivityResult]
     *
     * 这只是提供回调的功能，没有转换功能，所以建议在跳转的类里创建公开转换代码
     * 示例如下（activity需要id参数并返回字符串）：
     *  companion object {
     *      fun startResult(ui: IUIContext, id: Long, onResultOkCallback: (String) -> Unit) {
     *          ui.startActivityForResultCancelOk<TwoActivity>({
     *              putExtra("id", id)
     *          }) {
     *              onResultOkCallback.invoke(it?.getStringExtra("result") ?: return@startActivityForResultCancelOk)
     *          }
     *      }
     *  }
     *  @param context 启动的context，如果为null则会启动一个中间页来进行回调
     */
    @MainThread
    fun startActivityForResult(context: Context?, intent: Intent, resultCallback: (ActivityResult) -> Unit) {
        val reqCode = reqCodeIncrement.incrementAndGet()
        intent.putExtra(INTENT_CALLBACK_CHECK_KEY, reqCode)
        startDatas[reqCode] = resultCallback
        if (context is FragmentActivity) {
            val frag = StartActivityForResultFragment()
            frag.nextIntent = intent
            frag.reqCode = reqCode
            context.supportFragmentManager.beginTransaction()
                .add(frag, "StartActivityForResultFragment:$reqCode")
                .commitNowAllowingStateLoss()
        } else {
            (context ?: ActivityStackManager.getCurrentActivity() ?: singleApplication).startActivity(
                intentNew<StartActivityForResultActivity>()
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .putExtra("reqCode", reqCode)
                    .putExtra("nextIntent", intent)
            )
        }
    }

    /**
     * @return true：是回调式跳转并且被重建了，此时应该关闭当前页面，以防止出现操作无效的情况
     */
    fun isCallbackAndRebuild(intent: Intent?): Boolean {
        if (intent != null) {
            val reqCode = intent.getIntExtra(INTENT_CALLBACK_CHECK_KEY, -1)
            if (reqCode > 0 && startDatas[reqCode] == null) {
                return true
            }
        }
        return false
    }

    /**
     * 如果是FragmentActivity，则创建一个透明的Fragment
     */
    internal class StartActivityForResultFragment : Fragment() {
        var nextIntent: Intent? = null
        var reqCode = -1

        private val resultCall = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { callResult(it) }

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)

            nextIntent?.let { resultCall.launch(it) }
                ?: callResult(ActivityResult(Activity.RESULT_CANCELED, null))

            retainInstance = true //activity 异常重建时 ，fragment不重建
        }

        private fun callResult(result: ActivityResult) {
            startDatas[reqCode]?.invoke(result)
            startDatas.remove(reqCode)
            activity?.supportFragmentManager
                ?.beginTransaction()
                ?.remove(this)
                ?.commitAllowingStateLoss()
        }
    }

    /**
     * 如果非FragmentActivity或者null，则创建一个中间页
     */
    internal class StartActivityForResultActivity : AppCompatActivity() {
        private var nextIntent: Intent? = null

        private var reqCode = -1

        private val resultCall = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { callResult(it) }

        @SuppressLint("ClickableViewAccessibility")
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)

            nextIntent = intent.getParcelableExtra("nextIntent")
            reqCode = intent.getIntExtra("reqCode", -1)

            nextIntent?.let { resultCall.launch(it) }
                ?: callResult(ActivityResult(Activity.RESULT_CANCELED, null))

            val flRoot = View(this)
            //任何触碰都将会关闭页面，防止业务出现bug导致用户无法操作
            flRoot.setOnTouchListener { _, _ ->
                callResult(ActivityResult(Activity.RESULT_CANCELED, null))
                true
            }
            setContentView(flRoot)
            window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        }

        private fun callResult(result: ActivityResult) {
            startDatas[reqCode]?.invoke(result)
            startDatas.remove(reqCode)
            finish()
        }
    }
}
